package com.yaser.alfresco;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.text.MessageFormat;
import java.util.List;

import javax.faces.context.FacesContext;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientHandlerException;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.GenericType;
import com.sun.jersey.api.client.UniformInterfaceException;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.core.util.MultivaluedMapImpl;
import com.yaser.alfresco.model.AlfrescoFolder;
import com.yaser.alfresco.model.FileList;
import com.yaser.model.User;
import com.yaser.util.AlfrescoUtil;


@Component
@Scope("globalSession")
public class AlfrescoWebScripts {

	private static final String FILE_UPLOAD = "{0}/alfresco/service/com/yaser/uploadFile?alf_ticket={1}";
	private static final String DELETE_NODE = "{0}/alfresco/service/com/yaser/removeNode?nodeId={1}&alf_ticket={2}";
	private static final String LIST_CHILDREN = "{0}/alfresco/service/com/yaser/listchildren?nodeRef={1}&alf_ticket={2}";
	private static final String SEARCH_FILE = "{0}/alfresco/service/com/yaser/search?nodeRef={1}&search={2}&alf_ticket={3}";
	private static final String FIND_NODE = "{0}/alfresco/service/com/yaser/findNodeWithNodeRef?nodeRef={1}&alf_ticket={2}";
	private static final String COPY_NODE = "{0}/alfresco/service/util/copy?node={1}&target={2}&alf_ticket={3}";
	private static final String MOVE_NODE = "{0}/alfresco/service/com/yaser/move?node={1}&target={2}&alf_ticket={3}";
//	private static final String DOWNLOAD_FILE = "http://{0}:{1}/alfresco/download/attach/workspace/SpacesStore/{2}/{3}";
	private Client client =Client.create();
	private static String SERVICE_ERROR="Servis hizmeti tamamlayamadı. Hata kodu : ";
//	private static String SERVICE_URL="/alfresco/service/com/yaser/webscripts/";
	private static String SERVICE_URL="/alfresco/service/com/yaser/";


	/**
	 * 
	 * Creates a new folder into the given nodeId with given folderName
	 * 
	 * @param alf_ticket 	// ticket number given by the alfresco, to use web scripts
	 * @param host						// host ip of the alfresco server
	 * @param port						// port number of alfresco server to be connected
	 * @param nodeId		// id of any alfresco node		
	 * @param client		// jersey client object, if null, new client object is created
	 * @param folderName    // name of the folder to be created
	 * 
	 * @return
	 * 	Returns a new AlfrescoFolder entity or null if any exception
	 */
	public AlfrescoFolder createFolder(String alf_ticket, String baseUrl,String nodeId,String folderName,Client client) {

		if(alf_ticket==null&&baseUrl==null&&nodeId==null&&folderName==null){
			System.out.println("Hatalı parametre. Parametreleri kontrol edip tekrar deneyin");
			return null;
		}

		if(nodeId.contains("workspace"))
			nodeId = nodeId.substring(nodeId.lastIndexOf("/")+1);
		AlfrescoFolder createdfolder=null;
		try {
			if(client==null)
				client=Client.create();

			WebResource r = client.resource(baseUrl+""+SERVICE_URL+"createFolder?nodeId="+nodeId+"&folderName="+folderName+"&alf_ticket="+alf_ticket);

			ClientResponse response=null;

			response = r.accept(MediaType.APPLICATION_XML).get(ClientResponse.class);

			if (Response.Status.OK.getStatusCode() == response.getStatus()) {
				createdfolder = response.getEntity(AlfrescoFolder.class);
			} else {
				// TODO burada logger kullanılarak serverdan gelen response ın log dosyalarına uygun şeklinde yazılması gerekli
				return null;
			}
		} catch (UniformInterfaceException e) {
			System.out.println("Hata oluştu. Ayrıntı :\n"+e.getCause().getMessage());
		}
		return createdfolder;
	}
	
	public String fileUpload(String alf_ticket,String destinationNodeId,File file){

		if(alf_ticket==null&&destinationNodeId==null){
			return null;
		}
		
		if(!destinationNodeId.contains(AlfrescoUtil.ALFRESCO_STORE_PREFIX)){
			destinationNodeId=AlfrescoUtil.ALFRESCO_STORE_PREFIX+destinationNodeId;
		}
		
		String opResult="";
		
		HttpClient client = new DefaultHttpClient();
		HttpPost httppost = new HttpPost(MessageFormat.format(FILE_UPLOAD, AlfrescoUtil.BASE_URL, alf_ticket));
		FileBody bin = new FileBody(file);

		try {
			MultipartEntity reqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
			reqEntity.addPart("filedata", bin);
			reqEntity.addPart("destination",new StringBody(destinationNodeId));
			reqEntity.addPart("filename",new StringBody(file.getName()));
			httppost.setEntity(reqEntity);
			HttpResponse response = client.execute(httppost);

			
			if (Response.Status.OK.getStatusCode() == response.getStatusLine().getStatusCode()) {
				opResult = convertInputStreamToString(response.getEntity().getContent());
			} else {
				// TODO burada logger kullanılarak serverdan gelen response ın log dosyalarına uygun şeklinde yazılması gerekli
				opResult=SERVICE_ERROR+convertInputStreamToString(response.getEntity().getContent());
			}
		} catch (UnsupportedEncodingException e) {
			opResult="UnsupportedEncodingException : Detail : "+e.getMessage();
		} catch (ClientProtocolException e) {
			opResult="ClientProtocolException : Detail : "+e.getMessage();
		} catch (IOException e) {
			opResult="IOException : Detail : "+e.getMessage();
		}
		return opResult;
	}
	
	
	/** 
	 * method to convert an InputStream to a string using the BufferedReader.readLine() method 
	 * this methods reads the InputStream line by line until the null line is encountered 
	 * it appends each line to a StringBuilder object for optimal performance 
	 * @param is 
	 * @return 
	 * @throws IOException 
	 */  
	public static String convertInputStreamToString(InputStream inputStream) throws IOException  
	{  
		if (inputStream != null)  
		{  
			StringBuilder stringBuilder = new StringBuilder();  
			String line;  

			try {  
				BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));  
				while ((line = reader.readLine()) != null)  
				{  
					stringBuilder.append(line).append("\n");  
				}  
			}  
			finally  
			{  
				inputStream.close();  
			}  

			return stringBuilder.toString();  
		}  
		else  
		{  
			return null;  
		} 
	}
	

	
	
	/**
	 * 
	 * Creates a main folder for the new registered {@link User}
	 * 
	 * @param alf_ticket
	 * @param baseUrl
	 * @param nodeId
	 * @param folderName
	 * @param client
	 * @return
	 */
	public AlfrescoFolder createUserFolder(String alf_ticket,String folderName) {
		
		if(alf_ticket==null&&folderName==null){
			System.out.println("Hatalı parametre. Parametreleri kontrol edip tekrar deneyin");
			return null;
		}
		
		AlfrescoFolder createdfolder=null;
		try {
			WebResource r = client.resource(AlfrescoUtil.BASE_URL+SERVICE_URL+"createUser?folderName="+folderName+"&alf_ticket="+alf_ticket);
			
			ClientResponse response=null;
			
			response = r.accept(MediaType.APPLICATION_XML).get(ClientResponse.class);
			
			if (Response.Status.OK.getStatusCode() == response.getStatus()) {
				createdfolder = response.getEntity(AlfrescoFolder.class);
			} else {
				// TODO burada logger kullanılarak serverdan gelen response ın log dosyalarına uygun şeklinde yazılması gerekli
				return null;
			}
		} catch (UniformInterfaceException e) {
			System.out.println("Hata oluştu. Ayrıntı :\n"+e.getCause().getMessage());
		}
		return createdfolder;
	}
	
	public String uploadFile(String alf_ticket,String destinationNodeId,String fileName) throws IOException{
		if(alf_ticket==null&&destinationNodeId==null&&fileName==null){
			System.out.println("Hatalı parametre. Parametreleri kontrol edip tekrar deneyin");
			return null;
		}

		String opResult="";
		try {
			if(client==null)
				client=Client.create();

			File f = new File("C:/Users/Administrator/.m2/repository/commons-io/commons-io/1.4/commons-io-1.4.jar");

			InputStream ios = new FileInputStream(f);
			
			byte fileContent[] = new byte[(int)f.length()];
			ios.read(fileContent);
			
			System.out.println("Dosya boyutu : "+f.length());
			WebResource r = client.resource(MessageFormat
					.format(FILE_UPLOAD,
							AlfrescoUtil.BASE_URL, alf_ticket));

			ClientResponse response=null;

			MultivaluedMapImpl frm = new MultivaluedMapImpl();
			frm.add("fileName", fileName);
			frm.add("destinationNodeId", destinationNodeId);
			frm.add("content", f);
//			FormDataMultiPart form = new FormDataMultiPart().field("content", f, MediaType.MULTIPART_FORM_DATA_TYPE);
//			form.field("fileName", fileName);
//			form.field("destinationNodeId", destinationNodeId);
			
			r.header("http.protocol.expect-continue", "true");
			response = r.type(MediaType.MULTIPART_FORM_DATA).accept(MediaType.TEXT_PLAIN).post(ClientResponse.class, frm);


			if (Response.Status.OK.getStatusCode() == response.getStatus()) {
				opResult = response.getEntity(String.class);
			} else {
				// TODO burada logger kullanılarak serverdan gelen response ın log dosyalarına uygun şeklinde yazılması gerekli
				opResult=SERVICE_ERROR+response.getStatus();
				return opResult;
			}
		} catch (UniformInterfaceException e) {
			System.out.println("Hata oluştu. Ayrıntı :\n"+e.getCause().getMessage());
			opResult=e.getCause().getMessage();
		}

		return opResult;
	}
	
    public String deleteNode(String nodeId,String alf_ticket) {

        if (nodeId == null) {
            return null;
        }
        
        nodeId = nodeId.substring(nodeId.lastIndexOf("/")+1);
        
        String opResult = "";

        try {
            WebResource r = client.resource(MessageFormat.format(DELETE_NODE, AlfrescoUtil.BASE_URL, nodeId, alf_ticket));

            ClientResponse response = r.accept(MediaType.TEXT_PLAIN).get(ClientResponse.class);

            if (Response.Status.OK.getStatusCode() == response.getStatus()) {
                opResult = response.getEntity(String.class);
            } else {
                opResult = SERVICE_ERROR + response.getStatus();
            }
        } catch (UniformInterfaceException e) {
            opResult = e.getCause().getMessage();
        }
        return opResult;
    }


	public List<FileList> listChildrens(String alf_ticket,String nodeId) {

		if(alf_ticket==null&&nodeId==null){
			System.out.println("Hatalı parametre. Parametreleri kontrol edip tekrar deneyin");
			return null;
		}

		 if (!nodeId.startsWith(AlfrescoUtil.ALFRESCO_STORE_PREFIX)) {
	         nodeId = AlfrescoUtil.ALFRESCO_STORE_PREFIX+nodeId;
	     }
		
		List<FileList> f=null;
		try {
			if(client==null)
				client=Client.create();
			WebResource r = client.resource(MessageFormat.format(LIST_CHILDREN, AlfrescoUtil.BASE_URL, nodeId, alf_ticket));

			ClientResponse response=null;

			response = r.accept(MediaType.APPLICATION_XML).get(ClientResponse.class);

			if (Response.Status.OK.getStatusCode() == response.getStatus()) {
				f = response.getEntity(new GenericType<List<FileList>>() {});
			} else {
				// TODO burada logger kullanılarak serverdan gelen response ın log dosyalarına uygun şeklinde yazılması gerekli
				return null;
			}
		} catch (UniformInterfaceException e) {
			System.out.println("Hata oluştu. Ayrıntı :\n"+e.getCause().getMessage());
		} catch (ClientHandlerException e) {
			System.out.println("Hata oluştu. Ayrıntı :\n"+e.getCause().getMessage());
		}

		return f;

	}
	
	public void redirecToDownloadURL(FileList doc) {
        try {
            FacesContext.getCurrentInstance().getExternalContext().redirect(doc.getDownloadUrl());
        } catch (IOException e) {
//            throw new EPDKUIException("Doküman indirilemiyor.");
        }
    }
	
	
//    public File downloadFile(String nodeuuid, String documentName) {
//        File templateFile=null;
//
//        if (nodeuuid == null) {
////            log.debug(MISSING_PARAMETER);
//            return templateFile;
//        }
//        
//        if (nodeuuid.startsWith(AlfrescoUtil.ALFRESCO_STORE_PREFIX)) {
//            nodeuuid = nodeuuid.replaceAll(AlfrescoUtil.ALFRESCO_STORE_PREFIX, "");
//        }
//        
//        try {
//            InputStream input = DownloadHttpService.sendGetRequest(MessageFormat.format(DOWNLOAD_FILE,
//                    systemConfigurationManagementService.getAlfrescoHost(), systemConfigurationManagementService.getAlfrescoPort(), nodeuuid, URLEncoder.encode(documentName, "UTF-8")), ALFRESCO_CAS_HEADER, currentUser.getUsername());
//            
//            templateFile = File.createTempFile(documentName, null);
//            IOUtils.write(input, templateFile);
//        } catch (ClientHandlerException che) {
////            throw new AlfrescoServiceException(che);
//        } catch (Exception e) {
//            e.printStackTrace();
////            log.error("Download file error. IOException, error detail : " + e.getCause().getMessage());
//        }
//        return templateFile;
//    }
	
	
	public List<FileList> searchFilesByName(String baseNodeRef,String docName,String alf_ticket) {

		if(alf_ticket==null&&docName==null){
			System.out.println("Hatalı parametre. Parametreleri kontrol edip tekrar deneyin");
			return null;
		}

		 if (!baseNodeRef.startsWith(AlfrescoUtil.ALFRESCO_STORE_PREFIX)) {
	         baseNodeRef = AlfrescoUtil.ALFRESCO_STORE_PREFIX+baseNodeRef;
	     }
		
		List<FileList> f=null;
		try {
			if(client==null)
				client=Client.create();
			WebResource r = client.resource(MessageFormat.format(SEARCH_FILE, AlfrescoUtil.BASE_URL, baseNodeRef,docName, alf_ticket));

			ClientResponse response=null;

			response = r.accept(MediaType.APPLICATION_XML).get(ClientResponse.class);

			if (Response.Status.OK.getStatusCode() == response.getStatus()) {
				f = response.getEntity(new GenericType<List<FileList>>() {});
			} else {
				// TODO burada logger kullanılarak serverdan gelen response ın log dosyalarına uygun şeklinde yazılması gerekli
				return null;
			}
		} catch (UniformInterfaceException e) {
			System.out.println("Hata oluştu. Ayrıntı :\n"+e.getCause().getMessage());
		} catch (ClientHandlerException e) {
			System.out.println("Hata oluştu. Ayrıntı :\n"+e.getCause().getMessage());
		}

		return f;

	}
	
	
	public FileList findNode(String alf_ticket,String nodeId) {

		if(alf_ticket==null&&nodeId==null){
			System.out.println("Hatalı parametre. Parametreleri kontrol edip tekrar deneyin");
			return null;
		}

		 if (!nodeId.startsWith(AlfrescoUtil.ALFRESCO_STORE_PREFIX)) {
	         nodeId = AlfrescoUtil.ALFRESCO_STORE_PREFIX+nodeId;
	     }
		
		FileList f=null;
		try {
			if(client==null)
				client=Client.create();
			WebResource r = client.resource(MessageFormat.format(FIND_NODE, AlfrescoUtil.BASE_URL, nodeId, alf_ticket));

			ClientResponse response=null;

			response = r.accept(MediaType.APPLICATION_XML).get(ClientResponse.class);

			if (Response.Status.OK.getStatusCode() == response.getStatus()) {
				f = response.getEntity(FileList.class);
			} else {
				// TODO burada logger kullanılarak serverdan gelen response ın log dosyalarına uygun şeklinde yazılması gerekli
				return null;
			}
		} catch (UniformInterfaceException e) {
			System.out.println("Hata oluştu. Ayrıntı :\n"+e.getCause().getMessage());
		} catch (ClientHandlerException e) {
			System.out.println("Hata oluştu. Ayrıntı :\n"+e.getCause().getMessage());
		}

		return f;

	}
	

 public String move(String nodeToMove, String targetNode,String alf_ticket){

     if (nodeToMove == null && targetNode == null) {
    	 System.out.println("Hatalı parametre. Parametreleri kontrol edip tekrar deneyin");
         return null;
     }
//     if (nodeToMove.startsWith(AlfrescoUtil.ALFRESCO_STORE_PREFIX)) {
//         nodeToMove = nodeToMove.replace(AlfrescoUtil.ALFRESCO_STORE_PREFIX, "");
//     }
//
//     if (targetNode.startsWith(AlfrescoUtil.ALFRESCO_STORE_PREFIX)) {
//         targetNode = targetNode.replace(AlfrescoUtil.ALFRESCO_STORE_PREFIX , "");
//     }

     String opResult = "";

     try {

         WebResource r = client.resource(MessageFormat.format(MOVE_NODE, AlfrescoUtil.BASE_URL, nodeToMove, targetNode,alf_ticket));

         ClientResponse response = r.accept(MediaType.TEXT_PLAIN).get(ClientResponse.class);

         if (Response.Status.OK.getStatusCode() == response.getStatus()) {
             opResult = response.getEntity(String.class);
         } else {
        	 opResult="Error";
        	 System.out.println("Hata. Status :"+response.getStatus());
        	 System.out.println("Hata. Ayr�nt� :"+response.getEntity(String.class));
//             String causeMessage = ((JSONObject) JSONSerializer.toJSON(response.getEntity(String.class))).getString("exception");
         }
     } catch (ClientHandlerException che) {
         System.out.println("Alfresco Exception");
     } catch (UniformInterfaceException e) {
         opResult = e.getCause().getMessage();
     }
     return opResult;
 }
 
 
 
 public String copy(String nodeToCopy, String destinationFolderNodeRef,String alf_ticket){
	 
	 if (nodeToCopy == null && destinationFolderNodeRef == null) {
		 System.out.println("Hatalı parametre. Parametreleri kontrol edip tekrar deneyin");
		 return null;
	 }
	 if (!nodeToCopy.startsWith(AlfrescoUtil.ALFRESCO_STORE_PREFIX)) {
		 nodeToCopy = AlfrescoUtil.ALFRESCO_STORE_PREFIX + nodeToCopy;
	 }
	 
	 if (!destinationFolderNodeRef.startsWith(AlfrescoUtil.ALFRESCO_STORE_PREFIX)) {
		 destinationFolderNodeRef = AlfrescoUtil.ALFRESCO_STORE_PREFIX + destinationFolderNodeRef;
	 }
	 
	 String opResult = "";
	 
	 try {
		 
		 WebResource r = client.resource(MessageFormat.format(COPY_NODE, AlfrescoUtil.BASE_URL, nodeToCopy, destinationFolderNodeRef,alf_ticket));
		 
		 ClientResponse response = r.accept(MediaType.TEXT_PLAIN).get(ClientResponse.class);
		 
		 if (Response.Status.OK.getStatusCode() == response.getStatus()) {
			 opResult = response.getEntity(String.class);
		 } else {
			 opResult="Error";
			 System.out.println("Hata. Ayr�nt :"+response.getStatus());
//             String causeMessage = ((JSONObject) JSONSerializer.toJSON(response.getEntity(String.class))).getString("exception");
		 }
	 } catch (ClientHandlerException che) {
		 System.out.println("Alfresco Exception");
	 } catch (UniformInterfaceException e) {
		 opResult = e.getCause().getMessage();
	 }
	 return opResult;
 }
	
//	   public static String doUploadCall(String ticket, Map<String, Object>  parameters, UploadFile file, String url)throws HttpException, IOException{
//	         HttpClient client = new HttpClient();
//	       
//	         PostMethod method = new PostMethod(url + "?alf_ticket=" + ticket);     
//	         
//	         method.getParams().setBooleanParameter(HttpMethodParams.USE_EXPECT_CONTINUE, true);
//	         
//	         JSONObject json = JSONObject.fromObject(parameters);
//	       
//	         File f = new File(file.getFileName());
//	         OutputStream output = new FileOutputStream(f);
//	         IOUtils.copy(file.getInpuStream(), output);
//	       
//	         
//	         Part[] parts = {
//	               new StringPart("alf_ticket", ticket),
//	               new StringPart("parameters", json.toString()),
//	               new FilePart("file", f)
//	         }; 
//	         
//	         method.setRequestEntity(
//	               new MultipartRequestEntity(parts, method.getParams())
//	      );
//	         
//	         
//	         int statusCode = client.executeMethod(method);
//	         if (statusCode != HttpStatus.SC_OK) {
//	        System.err.println("Method failed: " + method.getStatusLine());
//	         } 
//	         return method.getResponseBodyAsString();
//	   }
	
}
